home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 2 / Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso / Pearls / tex / PasTeX14-BETA-6 / SpecialHost / Source / Post.c < prev    next >
C/C++ Source or Header  |  1994-07-14  |  16KB  |  630 lines

  1. /*
  2. **    SpecialHost for PasTeX
  3. **
  4. **    Copyright © by Olaf Barthel & Georg Heßmann
  5. */
  6.  
  7. #include "Global.h"
  8. #include "postlib.h"
  9.  
  10. /*#define DEBUG*/
  11.  
  12. #define INTOBP(x) ((float)(x*72.0))        /* converts 'inch' to 'big point' */
  13. #define INTOSP(x) ((float)(x*72.0*65781.76))    /* converts 'inch' to 'scaled point' */
  14. VOID __regargs PSGetSize(struct parse_result *Result, float *width, float *height, float *hoff, float *voff);
  15. VOID __regargs PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff);
  16.  
  17.  
  18.  
  19. struct Library *PostBase;
  20.  
  21. STATIC struct PSparm     PSparm;
  22. STATIC struct BitMap    *BitMap;
  23. STATIC PLANEPTR         Plane;
  24. STATIC LONG         ActivationRecord,
  25.              PlaneSize;
  26. STATIC BOOL         Transferred;
  27.  
  28. #ifdef DEBUG
  29. STATIC struct Screen    *LocalScreen;
  30. STATIC struct Window    *LocalWindow;
  31. #endif    /* DEBUG */
  32.  
  33. extern void insertftrap(void);
  34. extern void deleteftrap(void);
  35.  
  36. STATIC VOID __saveds
  37. CopyPage(VOID)
  38. {
  39.     CopyMem(Plane,BitMap -> Planes[0],PlaneSize);
  40.  
  41.     Transferred = TRUE;
  42.  
  43. #ifdef DEBUG
  44.     if(LocalScreen)
  45.     {
  46.         struct IntuiMessage *IntuiMessage;
  47.  
  48.         CopyMem(Plane,LocalScreen -> RastPort . BitMap -> Planes[0],LocalScreen -> RastPort . BitMap -> BytesPerRow * LocalScreen -> RastPort . BitMap -> Rows);
  49.  
  50.         ScreenToFront(LocalScreen);
  51.  
  52.         WaitPort(LocalWindow -> UserPort);
  53.  
  54.         while(IntuiMessage = (struct IntuiMessage *)GetMsg(LocalWindow -> UserPort))
  55.             ReplyMsg(IntuiMessage);
  56.     }
  57. #endif    /* DEBUG */
  58. }
  59.  
  60. void __saveds sigfpe(void)
  61. {
  62.     PSsignalfpe(ActivationRecord);
  63. }
  64.  
  65. void __saveds sigint(void)
  66. {
  67.     PSsignalint(ActivationRecord,1);
  68. }
  69.  
  70. struct BitMap * __regargs
  71. ProcessPostscript(struct special_msg *Message,struct special_map *SpecialMap,struct parse_result *Result,LONG *Error)
  72. {
  73.     *Error = 0;
  74.     
  75.     BitMap = NULL;
  76.  
  77.     if(PostBase = OpenLibrary("post.library",15))
  78.     {
  79.         BPTR NIL;
  80.  
  81.         if(NIL = Open("NIL:",MODE_READWRITE))
  82.         {
  83.             LONG    NewWidth,
  84.                 NewHeight,
  85.                 X_DPI = Message -> hresolution,
  86.                 Y_DPI = Message -> vresolution;
  87.             STRPTR special_string = NULL, sp;
  88.  
  89.             memset(&PSparm,0,sizeof(struct PSparm));
  90.  
  91.             PSGetSizeDot(Result, &NewWidth, &NewHeight, &(SpecialMap -> hoffset), &(SpecialMap -> voffset));
  92.  
  93.             SpecialMap -> width    = NewWidth;
  94.             SpecialMap -> height    = NewHeight;
  95.             
  96.             PSparm . page . xoff = SpecialMap -> hoffset;
  97.             PSparm . page . yoff = SpecialMap -> voffset;
  98.  
  99.             SpecialMap -> voffset = - SpecialMap -> voffset;
  100.  
  101.             special_string = AllocVecPooled(1024,MEMF_ANY);
  102.             sp = special_string;
  103.  
  104.             sprintf(sp,"TeXDict begin %d %d 1000 %d %d (noname) @start\n", \
  105.                 (LONG) (INTOSP((float) NewWidth/(float)X_DPI) + 0.5),  \
  106.                 (LONG) (INTOSP((float) NewHeight/(float)Y_DPI) + 0.5), \
  107.                 X_DPI, Y_DPI);
  108.             sp += strlen(sp);
  109.             sprintf(sp,"1 0 bop\nResolution neg VResolution neg vsize -72 div 1 add mul a @beginspecial\n");
  110.             sp += strlen(sp);
  111.  
  112.             if(Result -> gotcontrol & GOT_HSIZE)
  113.             {
  114.                 sprintf(sp,"%g @hsize ", INTOBP(Result -> hsize));
  115.                 sp += strlen(sp);
  116.             }
  117.  
  118.             if(Result -> gotcontrol & GOT_VSIZE)
  119.             {
  120.                 sprintf(sp,"%g @vsize ", INTOBP(Result -> vsize));
  121.                 sp += strlen(sp);
  122.             }
  123.  
  124.             if(Result -> gotcontrol & GOT_HSCALE)
  125.             {
  126.                 sprintf(sp,"%g @hscale ", Result -> hscale * 100.0);
  127.                 sp += strlen(sp);
  128.             }
  129.  
  130.             if(Result -> gotcontrol & GOT_VSCALE)
  131.             {
  132.                 sprintf(sp,"%g @vscale ", Result -> vscale * 100.0);
  133.                 sp += strlen(sp);
  134.             }
  135.  
  136.             if(Result -> gotcontrol & GOT_SCALE)
  137.             {
  138.                 sprintf(sp,"%g @hscale %g @vscale ", Result -> scale * 100.0, Result -> scale * 100.0);
  139.                 sp += strlen(sp);
  140.             }
  141.  
  142.             if(Result -> gotcontrol & GOT_HOFFSET)
  143.             {
  144.                 sprintf(sp,"%g @hoffset ", INTOBP(Result -> hoffset));
  145.                 sp += strlen(sp);
  146.             }
  147.  
  148.             if(Result -> gotcontrol & GOT_VOFFSET)
  149.             {
  150.                 sprintf(sp,"%g @voffset ", INTOBP(Result -> voffset));
  151.                 sp += strlen(sp);
  152.             }
  153.  
  154.             if (Result -> gotcontrol & GOT_ANGLE)
  155.             {
  156.                 sprintf(sp,"%g @angle ", Result -> angle);
  157.                 sp += strlen(sp);
  158.             }
  159.  
  160.             if (Result -> gotcontrol & GOT_CLIP)
  161.             {
  162.                 sprintf(sp,"@clip ");
  163.                 sp += strlen(sp);
  164.             }
  165.  
  166.             if(Result -> gotcontrol & SUFFICIENT_PS_ARGS)
  167.             {
  168.                 sprintf(sp,"%g @llx %g @lly %g @urx %g @ury %g @rwi ", \
  169.                     INTOBP(Result -> llx), INTOBP(Result -> lly),  \
  170.                     INTOBP(Result -> urx), INTOBP(Result -> ury),  \
  171.                     INTOBP(Result -> rwi));
  172.                 sp += strlen(sp);
  173.                 if(Result -> gotcontrol & GOT_RHI)
  174.                 {
  175.                     sprintf(sp,"%g @rhi ", INTOBP(Result -> rhi));
  176.                     sp += strlen(sp);
  177.                 }
  178.             }
  179.  
  180.             sprintf(sp,"@setspecial\n");
  181.             sp += strlen(sp);
  182.     
  183.             if(NewWidth > 30000 || NewHeight > 30000)
  184.                 *Error = ERR_TOO_LARGE;
  185.             else
  186.             {
  187.                 if(NewWidth < 1 || NewHeight < 1)
  188.                     *Error = ERR_TOO_SMALL;
  189.                 else
  190.                 {
  191.                     PrintLine("Page size %ld × %ld, %ld × %ld DPI",NewWidth,NewHeight,Message -> hresolution,Message -> vresolution);
  192.  
  193.                     if(BitMap = CreateBitMap(NewWidth,NewHeight,1,NULL,NULL))
  194.                     {
  195.                         if(Plane = (PLANEPTR)AllocVecPooled(PlaneSize = BitMap -> BytesPerRow * BitMap -> Rows,MEMF_ANY))
  196.                         {
  197.                             LONG ResultCode;
  198.  
  199.                             insertftrap();
  200.  
  201.                             PSparm . page . depth    = 1;
  202.                             PSparm . page . ydir    = -1;
  203.                             PSparm . page . xden    = X_DPI;
  204.                             PSparm . page . yden    = Y_DPI;
  205.                             PSparm . page . xsize    = NewWidth;
  206.                             PSparm . page . ysize    = NewHeight;
  207.                             PSparm . page . yheight    = NewHeight;
  208.                             PSparm . page . xbytes    = BitMap -> BytesPerRow;
  209.                             PSparm . page . len    = PSparm . page . xbytes * PSparm . page . ysize;
  210.                             PSparm . page . buf[0]    = Plane;
  211.  
  212.                             PSparm . copyfunc    = (APTR)CopyPage;
  213.                             PSparm . infh        = NIL;
  214.                             PSparm . outfh        = NIL;
  215.                             PSparm . errfh        = NIL;
  216.  
  217.                             ActivationRecord = PScreateact(&PSparm);
  218.  
  219.                             if(ActivationRecord <= errmax)
  220.                             {
  221.                                 if(ActivationRecord)
  222.                                     *Error = 20000 + ActivationRecord;
  223.                                 else
  224.                                     *Error = ERR_NO_MEM;
  225.                             }
  226.                             else
  227.                             {
  228.                                 ULONG Flags = PSFLAGCLEAR | PSFLAGERASE;
  229. #ifdef DEBUG
  230.                                 if(LocalScreen = OpenScreenTags(NULL,
  231.                                     SA_Width,    NewWidth,
  232.                                     SA_Height,    NewHeight,
  233.                                     SA_Depth,    1,
  234.                                     SA_DisplayID,    HIRESLACE_KEY,
  235.                                     SA_Quiet,    TRUE,
  236.                                     SA_AutoScroll,    TRUE,
  237.                                     SA_ShowTitle,    FALSE,
  238.                                     SA_Overscan,    OSCAN_STANDARD,
  239.                                 TAG_DONE))
  240.                                 {
  241.                                     if(!(LocalWindow = OpenWindowTags(NULL,
  242.                                         WA_Left,    0,
  243.                                         WA_Top,        0,
  244.                                         WA_Width,    LocalScreen -> Width,
  245.                                         WA_Height,    LocalScreen -> Height,
  246.                                         WA_RMBTrap,    TRUE,
  247.                                         WA_Backdrop,    TRUE,
  248.                                         WA_Borderless,    TRUE,
  249.                                         WA_CustomScreen,LocalScreen,
  250.                                         WA_Activate,    TRUE,
  251.                                         WA_IDCMP,    IDCMP_VANILLAKEY,
  252.                                     TAG_DONE)))
  253.                                     {
  254.                                         CloseScreen(LocalScreen);
  255.  
  256.                                         LocalScreen = NULL;
  257.                                     }
  258.                                 }
  259. #endif    /* DEBUG */
  260.                                 Transferred = FALSE;
  261.  
  262.                                 if(Result -> psinit_file[0] && !(*Error))
  263.                                 {
  264.                                     PrintLine("Executing initialization file...");
  265.     
  266.                                     if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_file,-1,PSFLAGFILE | Flags))
  267.                                         *Error = 20000 + ResultCode;
  268.                                     else
  269.                                         Flags = NULL;
  270.                                 }
  271.  
  272.                                 if(Result -> psinit_string[0] && !(*Error))
  273.                                 {
  274.                                     PrintLine("Executing initialization string...");
  275.     
  276.                                     if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_string,strlen(Result -> psinit_string),PSFLAGSTRING | Flags))
  277.                                         *Error = 20000 + ResultCode;
  278.                                     else
  279.                                         Flags = NULL;
  280.                                 }
  281. /*
  282.                                 if(!(*Error))
  283.                                 {
  284.                                     PrintLine("Executing file \"%s\"...","TeX:ps/finclude.pro");
  285.     
  286.                                     if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/finclude.pro",-1,PSFLAGFILE | Flags))
  287.                                         *Error = 20000 + ResultCode;
  288.                                     else
  289.                                         Flags = NULL;
  290.                                 }
  291.  
  292.                                 if(!(*Error))
  293.                                 {
  294.                                     PrintLine("Executing file \"%s\"...","TeX:ps/texps.pro");
  295.     
  296.                                     if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/texps.pro",-1,PSFLAGFILE | Flags))
  297.                                         *Error = 20000 + ResultCode;
  298.                                     else
  299.                                         Flags = NULL;
  300.                                 }
  301.  
  302.                                 if(!(*Error))
  303.                                 {
  304.                                     PrintLine("Executing file \"%s\"...","TeX:ps/special..pro");
  305.     
  306.                                     if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/special.pro",-1,PSFLAGFILE | Flags))
  307.                                         *Error = 20000 + ResultCode;
  308.                                     else
  309.                                         Flags = NULL;
  310.                                 }
  311.  
  312.                                 if(!(*Error))
  313.                                 {
  314.                                     PrintLine("Executing file \"%s\"...","TeX:ps/color.pro");
  315.     
  316.                                     if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/color.pro",-1,PSFLAGFILE | Flags))
  317.                                         *Error = 20000 + ResultCode;
  318.                                     else
  319.                                         Flags = NULL;
  320.                                 }
  321. */
  322.  
  323.                                 if(!(*Error))
  324.                                 {
  325.                                     PrintLine("Executing file \"%s\"...","TeX:ps/tex.pro");
  326.     
  327.                                     if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/tex.pro",-1,PSFLAGFILE | Flags))
  328.                                         *Error = 20000 + ResultCode;
  329.                                     else
  330.                                         Flags = NULL;
  331.                                 }
  332.  
  333.                                 if(!(*Error))
  334.                                 {
  335.                                     PrintLine("Executing file \"%s\"...","TeX:ps/special.pro");
  336.     
  337.                                     if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/special.pro",-1,PSFLAGFILE | Flags))
  338.                                         *Error = 20000 + ResultCode;
  339.                                     else
  340.                                         Flags = NULL;
  341.                                 }
  342.  
  343.                                 if (!(*Error))
  344.                                 {
  345.                                     PrintLine("Executing special string for @beginspecial...");
  346. //                                    Write(Output(),special_string,strlen(special_string));
  347.  
  348.                                     if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
  349.                                         *Error = 20000 + ResultCode;
  350.                                     else
  351.                                         Flags = NULL;                                    
  352.                                 }
  353.  
  354.                                 if(!(*Error))
  355.                                 {
  356.                                     PrintLine("Executing file \"%s\"...",Result -> psfile);
  357.     
  358.                                     if(ResultCode = PSintstring(ActivationRecord,Result -> psfile,-1,PSFLAGFILE | Flags))
  359.                                         *Error = 20000 + ResultCode;
  360.                                     else
  361.                                     {
  362.                                         if(!Transferred)
  363.                                         {
  364.                                             if(ResultCode = PSintstring(ActivationRecord,"showpage",8,PSFLAGSTRING))
  365.                                                 *Error = 20000 + ResultCode;
  366.                                         }                                        
  367.                                     }
  368.                                 }
  369.  
  370.                                 if (!(*Error))
  371.                                 {
  372.                                     PrintLine("Executing special string for @endspecial...");
  373.  
  374.                                     sprintf(special_string,"@endspecial eop end userdict /end-hook known{end-hook}if\n");
  375.                                     if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
  376.                                         *Error = 20000 + ResultCode;
  377.                                     else
  378.                                         Flags = NULL;                                    
  379.                                 }
  380.  
  381.                                 PSdeleteact(ActivationRecord);
  382. #ifdef DEBUG
  383.                                 if(LocalWindow)
  384.                                 {
  385.                                     CloseWindow(LocalWindow);
  386.  
  387.                                     LocalWindow = NULL;
  388.                                 }
  389.  
  390.                                 if(LocalScreen)
  391.                                 {
  392.                                     CloseScreen(LocalScreen);
  393.  
  394.                                     LocalScreen = NULL;
  395.                                 }
  396. #endif    /* DEBUG */
  397.                             }
  398.  
  399.                             deleteftrap();
  400.  
  401.                             FreeVecPooled(Plane);
  402.                         }
  403.                         else
  404.                             *Error = ERR_NO_MEM;
  405.  
  406.                         if(*Error)
  407.                         {
  408.                             DeleteBitMap(BitMap);
  409.  
  410.                             BitMap = NULL;
  411.                         }
  412.                     }
  413.                     else
  414.                         *Error = ERR_NO_MEM;
  415.                 }
  416.             }
  417.  
  418.             Close(NIL);
  419.             if (special_string) FreeVecPooled(special_string);
  420.         }
  421.         else
  422.             *Error = ERR_NO_NIL;
  423.  
  424.         CloseLibrary(PostBase);
  425.  
  426.         PostBase = NULL;
  427.     }
  428.     else
  429.         *Error = ERR_NO_POST;
  430.  
  431.     return(BitMap);
  432. }
  433.  
  434. /* Here are some functions to get the size of the PostScript picture */
  435.  
  436. #define TR_ROTATION    1
  437. #define    TR_SCALING    2
  438. #define TR_TRANSLATION    3
  439.  
  440. #define RAD(a) ((float)(a*3.1415926535358979324/180.0))
  441.  
  442. struct ctm {
  443.     float a,b,c,d,tx,ty;
  444.      };
  445.  
  446. struct bbox {
  447.     float llx, lly, urx, ury;
  448.     };
  449.  
  450. STATIC void ctm_transf(struct ctm *, float, float, int);
  451. STATIC void point_transf(struct ctm *, float, float, float *, float *);
  452. STATIC void bb_new(struct ctm *, struct bbox *, struct bbox *);
  453.  
  454. /* concatenates a transformation with the current transformation matrix. */
  455. static void ctm_transf(struct ctm *ctm, float x, float y, int transformation)
  456. {
  457.     float anew, bnew, cnew, dnew, costheta, sintheta;
  458.  
  459.     switch (transformation) {
  460.  
  461.         case TR_ROTATION:
  462.  
  463.             costheta = cos(x);
  464.             sintheta = sin(x);
  465.             anew =   ctm -> a * costheta + ctm -> c * sintheta;
  466.             bnew =   ctm -> b * costheta + ctm -> d * sintheta;
  467.             cnew = - ctm -> a * sintheta + ctm -> c * costheta;
  468.             dnew = - ctm -> b * sintheta + ctm -> d * costheta;
  469.             ctm -> a = anew;
  470.             ctm -> b = bnew;
  471.             ctm -> c = cnew;
  472.             ctm -> d = dnew;
  473.             break;
  474.  
  475.         case TR_SCALING:
  476.  
  477.             ctm -> a *= x;
  478.             ctm -> b *= x;
  479.             ctm -> c *= y;
  480.             ctm -> d *= y;
  481.             break;
  482.     
  483.         case TR_TRANSLATION:
  484.  
  485.  
  486.             ctm -> tx += ctm -> a * x + ctm -> c * y;
  487.             ctm -> ty += ctm -> b * x + ctm -> d * y;
  488.             break;
  489.  
  490.         default:
  491.  
  492.             break;
  493.     }
  494. }
  495.  
  496.  
  497. /* Given a point (x,y) and the current transformation matrix ctm, returns
  498.    the transformed point (x1,y1). */
  499. static void point_transf(struct ctm *ctm, float x, float y, float *x1, float *y1)
  500. {
  501.     *x1 = ctm -> a * x + ctm -> c * y + ctm -> tx;
  502.     *y1 = ctm -> b * x + ctm -> d * y + ctm -> ty;
  503. }
  504.  
  505.  
  506. /* Given the current transformation matrix and a bounding box, 
  507.    returns the transformed bounding box. */
  508. static void bb_new(struct ctm *ctm, struct bbox *bb, struct bbox *bbnew) {
  509.     
  510.     float x0,y0,x1,y1,x2,y2,x3,y3,xmin,xmax,ymin,ymax;
  511.  
  512.     xmin = ymin =  1.0e20;
  513.     xmax = ymax = -1.0e20;
  514.  
  515.     point_transf(ctm, bb -> llx, bb -> lly, &x0, &y0);
  516.     point_transf(ctm, bb -> urx, bb -> lly, &x1, &y1);
  517.     point_transf(ctm, bb -> urx, bb -> ury, &x2, &y2);
  518.     point_transf(ctm, bb -> llx, bb -> ury, &x3, &y3);
  519.     
  520.     xmin = min(xmin,x0);    ymin = min(ymin,y0);
  521.     xmin = min(xmin,x1);    ymin = min(ymin,y1);
  522.     xmin = min(xmin,x2);    ymin = min(ymin,y2);
  523.     xmin = min(xmin,x3);    ymin = min(ymin,y3);
  524.     xmax = max(xmax,x0);    ymax = max(ymax,y0);
  525.     xmax = max(xmax,x1);    ymax = max(ymax,y1);
  526.     xmax = max(xmax,x2);    ymax = max(ymax,y2);
  527.     xmax = max(xmax,x3);    ymax = max(ymax,y3);
  528.  
  529.     bbnew -> llx = xmin;
  530.     bbnew -> lly = ymin;
  531.     bbnew -> urx = xmax;
  532.     bbnew -> ury = ymax;
  533. }
  534.  
  535.  
  536. /* Given a pointer to a struct 'parse_result', returns width, height,
  537.    hoffset, voffset of the picture, in inch. */
  538. VOID __regargs PSGetSize(struct parse_result *Result, float *width, float *height, float *hoff, float *voff)
  539. {
  540.     float    hscale=1.0,    vscale=1.0,
  541.         hscale_rxi=1.0,    vscale_rxi=1.0,
  542.         hoffset=0.0,    voffset=0.0,
  543.         angle=0.0;
  544.  
  545.     struct bbox bb, bbnew;
  546.     struct ctm ctm;
  547.  
  548.     bb . llx = 0.0;
  549.     bb . lly = 0.0;
  550.     bb . urx = 8.0;        /* default width  = 8in */
  551.     bb . ury = 11.0;    /* default height = 11in */
  552.  
  553. /* initialize the current transformation matrix with the identity matrix */
  554.     ctm.a = ctm.d = 1.0;
  555.     ctm.b = ctm.c = ctm.tx = ctm.ty = 0.0;
  556.  
  557.     if (Result -> gotcontrol & GOT_HSCALE)
  558.         hscale = Result -> hscale;
  559.     
  560.     if (Result -> gotcontrol & GOT_VSCALE)
  561.         vscale = Result -> vscale;
  562.  
  563.     if (Result -> gotcontrol & GOT_SCALE)
  564.         hscale = vscale = Result -> scale;
  565.  
  566.     if (Result -> gotcontrol & GOT_HOFFSET)
  567.         hoffset = Result -> hoffset;
  568.  
  569.     if (Result -> gotcontrol & GOT_VOFFSET)
  570.         voffset = Result -> voffset;
  571.  
  572.     if (Result -> gotcontrol & GOT_ANGLE)
  573.         angle = Result -> angle;
  574.  
  575.     if (Result -> gotcontrol & SUFFICIENT_PS_ARGS) {
  576.         bb . llx = Result -> llx;
  577.         bb . lly = Result -> lly;
  578.         bb . urx = Result -> urx;
  579.         bb . ury = Result -> ury;
  580.  
  581.         hscale_rxi = Result -> rwi / (10.0 * (bb . urx - bb . llx));
  582.  
  583.         if (Result -> gotcontrol & GOT_RHI)
  584.             vscale_rxi = Result -> rhi / (10.0 * (bb. ury - bb . lly));
  585.         else
  586.             vscale_rxi = hscale_rxi;
  587.     }
  588.  
  589. /* Performs PostScript transformations */
  590.     ctm_transf(&ctm, hoffset, voffset, TR_TRANSLATION);
  591.     ctm_transf(&ctm, hscale, vscale, TR_SCALING);
  592.     ctm_transf(&ctm, RAD(angle), 0.0f, TR_ROTATION);
  593.     ctm_transf(&ctm, hscale_rxi, vscale_rxi, TR_SCALING);
  594.     ctm_transf(&ctm, (float)-bb.llx, (float)-bb.lly,TR_TRANSLATION);
  595.  
  596.     bb_new(&ctm, &bb, &bbnew);
  597.     *width    = bbnew . urx - bbnew . llx;
  598.     *height    = bbnew . ury - bbnew . lly;
  599.     *hoff = bbnew . llx;
  600.     *voff = bbnew . lly;
  601.  
  602. /* hsize & vsize define the clipping area; the clipping area isn't
  603.    affected by scaling, translation or rotation. */
  604.  
  605.     if (Result -> gotcontrol & GOT_HSIZE)
  606.     {
  607.         *width = Result -> hsize ;
  608.         *hoff  = 0.0;
  609.     }
  610.  
  611.     if (Result -> gotcontrol & GOT_VSIZE)
  612.     {
  613.         *height = Result -> vsize ;
  614.         *voff = 0.0;
  615.     }
  616. }
  617.  
  618. /* Same of PSGetSize but returns width, height, hoffset, voffset
  619.    in 'dot' or 'pixels', using 'Result->hres' and 'Result->vres'. */
  620. VOID __regargs PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff)
  621. {
  622.     float f_width, f_height, f_hoff, f_voff;
  623.  
  624.     PSGetSize(Result, &f_width, &f_height, &f_hoff, &f_voff);
  625.     *width    = (LONG)(f_width  * (float) Result -> hres + 0.5);
  626.     *height    = (LONG)(f_height * (float) Result -> vres + 0.5);
  627.     *hoff    = (LONG)(f_hoff   * (float) Result -> hres + 0.5);
  628.     *voff    = (LONG)(f_voff   * (float) Result -> vres + 0.5);
  629. }
  630.